package santeclair.referentiel.optique.referentiel.dao.impl;

import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.PersistenceContext;
import javax.persistence.TypedQuery;

import org.springframework.stereotype.Repository;

import santeclair.lunar.framework.dao.jpa.exception.JpaExceptionHelper;
import santeclair.lunar.framework.dao.jpa.impl.FwkCodeJpaDAO;
import santeclair.referentiel.optique.config.Constant;
import santeclair.referentiel.optique.model.SupplementVerre;
import santeclair.referentiel.optique.referentiel.dao.SupplementVerreDAO;

@Repository
public class SupplementVerreDAOImpl extends FwkCodeJpaDAO<SupplementVerre, String> implements SupplementVerreDAO {

    @PersistenceContext(unitName = Constant.PERSISTENCE_UNIT_NAME)
    private EntityManager em;

    @Override
    public Class<SupplementVerre> getEntityClass() {
        return SupplementVerre.class;
    }

    @Override
    public EntityManager getEntityManager() {
        return em;
    }

    @Override
    public Boolean supplementExistByCodeOpto10(String codeOpto10) {
        Long size = this.getSizeByParameter("codeOpto10SupplementVerre", codeOpto10);
        return size != null && size.intValue() > 0;
    }

    @Override
    public String findCodeTraitementByCodeOpto10FabricantSupplement(String codeOpto10FabricantOptique, String codeOpto10DistributeurOptique, String codeOpto10Verre,
                    String codeOpto10SupplementVerre) throws IllegalArgumentException, NoResultException {
        String codeTraitement = null;

        StringBuffer sbf = new StringBuffer();
        sbf.append("SELECT trtGrille.codeTraitementGrille ");
        sbf.append("FROM Verre as leVerre ");

        sbf.append("    JOIN leVerre.fabricantOptique as fab ");
        sbf.append("    JOIN leVerre.distributeurOptique as distributeur ");
        sbf.append("    JOIN leVerre.supplementVerres as supplement ");
        sbf.append("    JOIN supplement.traitementGrille as trtGrille ");

        sbf.append("WHERE fab.codeOpto10FabricantOptique = :codeOpto10FabricantOptique ");
        sbf.append("AND distributeur.codeOpto10DistributeurOptique = :codeOpto10DistributeurOptique ");
        sbf.append("AND leVerre.codeOpto10Verre = :codeOpto10Verre ");
        sbf.append("AND supplement.codeOpto10SupplementVerre = :codeOpto10SupplementVerre ");

        TypedQuery<String> query = em.createQuery(sbf.toString(), String.class);

        query.setParameter("codeOpto10FabricantOptique", codeOpto10FabricantOptique);
        query.setParameter("codeOpto10DistributeurOptique", codeOpto10DistributeurOptique);
        query.setParameter("codeOpto10Verre", codeOpto10Verre);
        query.setParameter("codeOpto10SupplementVerre", codeOpto10SupplementVerre);

        codeTraitement = query.getSingleResult();

        return codeTraitement;
    }

    @Override
    public SupplementVerre findFetchedSupplementByCodeOpto10SupplementVerreAndCodeFabricantOptique(String codeOpto10SupplementVerre, String codeFabricantOptique) {
        StringBuffer sbf = new StringBuffer();
        sbf.append("SELECT supplementVerre ");
        sbf.append("FROM SupplementVerre as supplementVerre ");
        sbf.append("    LEFT JOIN FETCH supplementVerre.fabricantOptique as fabricant ");
        sbf.append("    LEFT JOIN FETCH supplementVerre.traitementGrille as trtGrille ");
        sbf.append("    LEFT JOIN FETCH trtGrille.traitementVerre as trtVerre ");
        sbf.append("WHERE fabricant.codeFabricantOptique = :codeFabricantOptique ");
        sbf.append("AND supplementVerre.codeOpto10SupplementVerre = :codeOpto10SupplementVerre ");
        TypedQuery<SupplementVerre> query = null;
        try {
            query = em.createQuery(sbf.toString(), SupplementVerre.class);

            query.setParameter("codeFabricantOptique", codeFabricantOptique);
            query.setParameter("codeOpto10SupplementVerre", codeOpto10SupplementVerre);

            return query.getSingleResult();
        } catch (Exception e) {
            throw JpaExceptionHelper.addQueryInformation(sbf.toString(), query, e, RuntimeException.class);
        }

    }
}
